#pragma once

#include <stdlib.h>
#include <string>
#include <stdio.h>

#ifdef __WIN32__

	#include <winsock2.h>

#else

	#define INVALID_SOCKET -1

	#include <sys/socket.h>
	#include <sys/types.h>

#endif


/*
 * Flags used for communicating between two nodes
 * These flags are important because they distinquish
 * different types of messages. The server and client
 * are to react appropriately based on what type of
 * message is being recieved.
 *****************************************************/
typedef enum
{
	CORRUPT,

	// Client notifies server of disconnect
	CLIENT_DISCONNECT,

	// Server notifies client(s) of shutdown
	SERVER_DISCONNECT,

	// Server notifies clients of a room join.
	SERVER_NOTIFY_JOIN,

	// Client requests to use a specific username.
	CLIENT_REQUEST_NAME,

	// Server notifies clients of client rename
	SERVER_CLIENT_RENAME,

	// Server lists users in room.
	LIST_USERS,

	// Client sent message.
	CLIENT_MESSAGE,

	// Server sent message.
	SERVER_MESSAGE,

	//
	SEND_FILE,

} DispatchFlag;

/*
 * Number of bits reserved for data to be sent
 *****************************************************/
#define DATA_SIZE 512

/*
 * The Dispatch class is used to pass information back
 * and forth between two connections
 *****************************************************/
class Dispatch {

	public:
		// Basic constructor
		Dispatch( void );

		// Set flag and data
		Dispatch( DispatchFlag flag, std::string data = "" );

		// Send packet over socket
		bool release( int sock ) const;

		// Receive a packet via socket
		long receive( int sock );
		// Same as above, use last used socket
		long receive( void );

		// Returns data of packet.
		const std::string getData( void ) const;

		// Return flag of packet.
		const DispatchFlag getFlag( void ) const;

		// Return size in bytes
		long getBytes( void ) const;

		// Return socket of packet.
		int getSocket( void ) const;

		// Return the length of data in the packet
		long getDataLength( void ) const;

		// Set packet flag
		void setFlag( DispatchFlag flag );

		// Set packet data
		void setData( std::string data );

		// set packet data length call this to seer the length of the packet
		long setDataLength( void );

		// Calculate and set data bytes. Call this to calculate the bytes of the packet
		long setBytes( void );

		// Explicitly set the bytes of the packet
		long setBytes( long );

	private:
		// Character String holding packet data.
		std::string data;

		// Character string holding flag of packet.
		DispatchFlag flag;

		// Holds the length of data from packet
		long dataLength;

		// Number of bytes in packet
		long bytes;

		// Socket
		int socket;
};
